package com.foodorder.service;

import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.UUID;

/**
 * 文件上传服务（支持本地存储和OSS）
 */
@Service
@Slf4j
public class OssService {
    
    @Value("${oss.enabled:false}")
    private boolean ossEnabled;
    
    @Value("${file.upload.local-path:./uploads}")
    private String localPath;
    
    @Value("${file.upload.allowed-image-types:jpg,jpeg,png,gif,webp,bmp}")
    private String allowedImageTypes;
    
    @Value("${oss.aliyun.domain:http://localhost:8080}")
    private String ossDomain;
    
    /**
     * 上传文件
     * 
     * @param file 要上传的文件
     * @param fileType 文件类型（banner、product、store、user、category）
     * @return 文件访问URL
     */
    public String uploadFile(MultipartFile file, String fileType) {
        if (file == null || file.isEmpty()) {
            throw new RuntimeException("文件不能为空");
        }
        
        // 验证文件类型
        validateFileType(file);
        
        // 验证文件大小 (10MB)
        if (file.getSize() > 10 * 1024 * 1024) {
            throw new RuntimeException("文件大小不能超过10MB");
        }
        
        try {
            if (ossEnabled) {
                // TODO: 实现真实的OSS上传逻辑
                return uploadToOssSimulated(file, fileType);
            } else {
                return uploadToLocal(file, fileType);
            }
        } catch (Exception e) {
            log.error("文件上传失败", e);
            throw new RuntimeException("文件上传失败: " + e.getMessage());
        }
    }
    
    /**
     * 模拟OSS上传（实际保存到本地）
     */
    private String uploadToOssSimulated(MultipartFile file, String fileType) throws IOException {
        // 生成文件名
        String fileName = generateFileName(file.getOriginalFilename(), fileType);
        
        // 创建本地存储目录
        Path directory = Paths.get(localPath, fileType);
        if (!Files.exists(directory)) {
            Files.createDirectories(directory);
        }
        
        // 保存文件
        Path targetPath = directory.resolve(fileName.substring(fileName.lastIndexOf("/") + 1));
        Files.copy(file.getInputStream(), targetPath);
        
        // 返回模拟的OSS URL
        String fileUrl = ossDomain + "/uploads/" + fileName;
        
        log.info("文件上传成功 (模拟OSS): {}", fileUrl);
        return fileUrl;
    }
    
    /**
     * 上传到本地存储
     */
    private String uploadToLocal(MultipartFile file, String fileType) throws IOException {
        // 生成文件名
        String fileName = generateFileName(file.getOriginalFilename(), fileType);
        
        // 创建本地存储目录
        Path directory = Paths.get(localPath, fileType);
        if (!Files.exists(directory)) {
            Files.createDirectories(directory);
        }
        
        // 保存文件
        Path targetPath = directory.resolve(fileName.substring(fileName.lastIndexOf("/") + 1));
        Files.copy(file.getInputStream(), targetPath);
        
        // 返回文件访问URL（相对路径）
        String fileUrl = "/uploads/" + fileName;
        
        log.info("文件保存到本地: {}", fileUrl);
        return fileUrl;
    }
    
    /**
     * 生成唯一文件名
     */
    private String generateFileName(String originalFilename, String fileType) {
        // 获取文件扩展名
        String extension = "";
        if (originalFilename != null && originalFilename.contains(".")) {
            extension = originalFilename.substring(originalFilename.lastIndexOf("."));
        }
        
        // 生成时间戳
        String timestamp = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMdd/HHmmss"));
        
        // 生成UUID
        String uuid = UUID.randomUUID().toString().replace("-", "");
        
        // 组合文件名：fileType/yyyyMMdd/HHmmss_uuid.extension
        return fileType + "/" + timestamp + "_" + uuid + extension;
    }
    
    /**
     * 验证文件类型
     */
    private void validateFileType(MultipartFile file) {
        String originalFilename = file.getOriginalFilename();
        if (originalFilename == null) {
            throw new RuntimeException("文件名不能为空");
        }
        
        String extension = originalFilename.substring(originalFilename.lastIndexOf(".") + 1).toLowerCase();
        String[] allowedTypes = allowedImageTypes.split(",");
        
        boolean isAllowed = false;
        for (String allowedType : allowedTypes) {
            if (allowedType.trim().equals(extension)) {
                isAllowed = true;
                break;
            }
        }
        
        if (!isAllowed) {
            throw new RuntimeException("不支持的文件类型: " + extension + "，仅支持: " + allowedImageTypes);
        }
    }
    
    /**
     * 删除文件
     */
    public boolean deleteFile(String fileUrl) {
        if (fileUrl == null || fileUrl.isEmpty()) {
            return false;
        }
        
        try {
            // 解析文件路径
            String filePath;
            if (fileUrl.startsWith(ossDomain + "/uploads/")) {
                filePath = fileUrl.replace(ossDomain + "/uploads/", "");
            } else if (fileUrl.startsWith("/uploads/")) {
                filePath = fileUrl.replace("/uploads/", "");
            } else {
                return false;
            }
            
            // 删除本地文件
            Path targetPath = Paths.get(localPath, filePath);
            if (Files.exists(targetPath)) {
                Files.delete(targetPath);
                log.info("文件删除成功: {}", fileUrl);
                return true;
            }
        } catch (Exception e) {
            log.error("文件删除失败: {}", fileUrl, e);
        }
        
        return false;
    }
    
    /**
     * 检查文件是否存在
     */
    public boolean fileExists(String fileUrl) {
        if (fileUrl == null || fileUrl.isEmpty()) {
            return false;
        }
        
        try {
            // 解析文件路径
            String filePath;
            if (fileUrl.startsWith(ossDomain + "/uploads/")) {
                filePath = fileUrl.replace(ossDomain + "/uploads/", "");
            } else if (fileUrl.startsWith("/uploads/")) {
                filePath = fileUrl.replace("/uploads/", "");
            } else {
                return false;
            }
            
            Path targetPath = Paths.get(localPath, filePath);
            return Files.exists(targetPath);
        } catch (Exception e) {
            log.error("检查文件是否存在时发生错误: {}", fileUrl, e);
        }
        
        return false;
    }
    
    /**
     * 上传图片文件（便捷方法）
     */
    public String uploadImage(MultipartFile file) {
        return uploadFile(file, "images");
    }
    
    /**
     * 上传Banner图片（便捷方法）
     */
    public String uploadBanner(MultipartFile file) {
        return uploadFile(file, "banner");
    }
    
    /**
     * 上传商品图片（便捷方法）
     */
    public String uploadProduct(MultipartFile file) {
        return uploadFile(file, "product");
    }
    
    /**
     * 上传店铺图片（便捷方法）
     */
    public String uploadStore(MultipartFile file) {
        return uploadFile(file, "store");
    }
    
    /**
     * 上传用户头像（便捷方法）
     */
    public String uploadUser(MultipartFile file) {
        return uploadFile(file, "user");
    }
} 